/**
 * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
 */
package com.jeeplus.modules.sys.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jeeplus.common.utils.*;
import com.jeeplus.core.security.Digests;
import com.jeeplus.core.security.shiro.session.SessionDAO;
import com.jeeplus.core.service.CrudService;
import com.jeeplus.core.service.ServiceException;
import com.jeeplus.modules.sys.entity.*;
import com.jeeplus.modules.sys.mapper.UserMapper;
import com.jeeplus.modules.sys.utils.UserUtils;
import org.apache.shiro.session.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 用户管理
 * @author jeeplus
 * @version 2016-12-05
 */
@Service
@Transactional(readOnly = true)
public class UserService  extends CrudService<UserMapper, User> {
	
	public static final int HASH_INTERATIONS = 1024;
	public static final int SALT_SIZE = 8;

	@Autowired
	private SessionDAO sessionDao;
	public SessionDAO getSessionDao() {
		return sessionDao;
	}
	@Autowired
	private UserMapper userMapper;
	/**
	 * 获取用户
	 * @param id
	 * @return
	 */
	public User get(String id) {
		return UserUtils.get(id);
	}

	/**
	 * 根据登录名获取用户
	 * @param loginName
	 * @return
	 */
	public User getUserByLoginName(String loginName) {
		return UserUtils.getByLoginName(loginName);
	}
	

	/**
	 * 通过部门ID获取用户列表，仅返回用户id和name（树查询用户时用）
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<User> findUserByOfficeId(String officeId) {
		List<User> list = (List<User>)CacheUtils.get(UserUtils.USER_CACHE, UserUtils.USER_CACHE_LIST_BY_OFFICE_ID_ + officeId);
		if (list == null){
			User user = new User();
			user.setOffice(new Office(officeId));
			list = mapper.findUserByOfficeId(user);
			CacheUtils.put(UserUtils.USER_CACHE, UserUtils.USER_CACHE_LIST_BY_OFFICE_ID_ + officeId, list);
		}
		return list;
	}
	
	@Transactional(readOnly = false)
	public void saveUser(User user) {
		if (StringUtils.isBlank(user.getId())){
			user.preInsert();
			mapper.insert(user);
		}else{
			// 清除原用户机构用户缓存
			User oldUser = mapper.get(user.getId());
			if (oldUser.getOffice() != null && oldUser.getOffice().getId() != null){
				CacheUtils.remove(UserUtils.USER_CACHE, UserUtils.USER_CACHE_LIST_BY_OFFICE_ID_ + oldUser.getOffice().getId());
			}
			// 更新用户数据
			user.preUpdate();
			mapper.update(user);
		}
		if (StringUtils.isNotBlank(user.getId())){
			// 更新用户与角色关联
			mapper.deleteUserRole(user);
			if (user.getRoleList() != null && user.getRoleList().size() > 0){
				mapper.insertUserRole(user);
			}else{
				throw new ServiceException(user.getLoginName() + "没有设置角色！");
			}
			// 清除用户缓存
			UserUtils.clearCache(user);
		}
	}

	@Transactional(readOnly = false)
	public void saveUserOther(String openid,String userid,String tell,String url) {
		Integer result = mapper.findUserMatter(openid);
		if(result == null || result == 0){
			mapper.insertOther(openid,userid,tell,url);
		}else{
			mapper.updateOther(openid,userid,tell,url);
		}
	}

	/**
	 * 更新跳转地址
	 * @return
	 */
	@Transactional(readOnly = false)
	public void updateUrl(String openid,String url){
		mapper.updateUrl(openid,url);
	}
	
	@Transactional(readOnly = false)
	public void updateUserInfo(User user) {
		user.preUpdate();
		mapper.updateUserInfo(user);
		// 清除用户缓存
		UserUtils.clearCache(user);
	}

	@Transactional(readOnly = false)
	public void updateUser(User user) {
		user.preUpdate();
		mapper.updateUser(user.getLoginName());
		// 清除用户缓存
		UserUtils.clearCache(user);
	}
	
	@Transactional(readOnly = false)
	public void deleteUser(User user) {
		mapper.deleteUserRole(user);
		mapper.delete(user);
		// 清除用户缓存
		UserUtils.clearCache(user);
	}
	public Integer getUserPhone(String tell){
		return userMapper.getUserPhone(tell);
	}
	
	@Transactional(readOnly = false)
	public void updatePasswordById(String id, String loginName, String newPassword) {
		User user = new User(id);
		user.setPassword(entryptPassword(newPassword));
		mapper.updatePasswordById(user);
		// 清除用户缓存
		user.setLoginName(loginName);
		UserUtils.clearCache(user);
	}
	
	@Transactional(readOnly = false)
	public void updateUserLoginInfo(User user) {
		// 保存上次登录信息
		user.setOldLoginIp(user.getLoginIp());
		user.setOldLoginDate(user.getLoginDate());
		// 更新本次登录信息
		user.setLoginIp(UserUtils.getSession().getHost());
		user.setLoginDate(new Date());
		mapper.updateLoginInfo(user);
	}

	/**
	 * 生成安全的密码，生成随机的16位salt并经过1024次 sha-1 hash
	 */
	public static String entryptPassword(String plainPassword) {
		byte[] salt = Digests.generateSalt(SALT_SIZE);
		byte[] hashPassword = Digests.sha1(plainPassword.getBytes(), salt, HASH_INTERATIONS);
		return Encodes.encodeHex(salt)+Encodes.encodeHex(hashPassword);
	}

	/**
	 * 验证密码
	 * @param plainPassword 明文密码
	 * @param password 密文密码
	 * @return 验证成功返回true
	 */
	public static boolean validatePassword(String plainPassword, String password) {
		byte[] salt = Encodes.decodeHex(password.substring(0,16));
		byte[] hashPassword = Digests.sha1(plainPassword.getBytes(), salt, HASH_INTERATIONS);
		return password.equals(Encodes.encodeHex(salt)+Encodes.encodeHex(hashPassword));
	}

	/**
	 * 获得活动会话
	 * @return
	 */
	public Collection<Session> getActiveSessions(){
		return sessionDao.getActiveSessions(false);
	}


	public Map<String,String> getSSOUser(int id){
		Map<String, String> ssoUser = userMapper.getSSOUser(id);


		return ssoUser;
	}

	public List<String> findAll(){
		List<String> allID = userMapper.findAllID();
		return allID;
	}
	@Transactional(readOnly = false)
	public void addUser(User user){
		userMapper.insert(user);
		mapper.deleteUserRole(user);
		mapper.insertUserRole(user);
	}

	@Transactional(readOnly = false)
	public void insertQR(String uuid,String createTime,int loseTime,String loginName,String tell){
		userMapper.insertQR(uuid,createTime,loseTime,loginName,tell);
	}

	public MobileUserQR getUserCode(String uuid, int loseTime){
		return userMapper.getUserCode(uuid,loseTime);
	}

	public MobileUserQR getUserIdcard(String loginName){
		return userMapper.getUserIdcard(loginName);
	}

	public MobileUserQR getUserIdcardByTell(String tell){
		return userMapper.getUserIdcardByTell(tell);
	}

	public User findUser(String loginName){
		return userMapper.findUser(loginName);
	}

	@Transactional(readOnly = false)
	public int toThingCode(String code,String loginName,String doTime,int isYYYZ){
		return userMapper.toThingCode(code,loginName,doTime,isYYYZ);
	}

	public String findUserQcode(String id){
		return userMapper.findUserQcode(id);
	}

	public PageBean<User> getUserList(String pageNo, String pageSize,String orderBy ,String loginName,String name){
		PageBean<User> pageBean = new PageBean<>();
		PageHelper.startPage(Integer.parseInt(pageNo), Integer.parseInt(pageSize));
		if(StringUtils.isNotBlank(orderBy)){
			PageHelper.orderBy(orderBy);
		}
		if(StringUtils.isNotBlank(loginName)){
			loginName = "%"+loginName+"%";
		}
		if(StringUtils.isNotBlank(name)){
			name = "%"+name+"%";
		}
		List<User> list = userMapper.getUserList(loginName,name);
		PageInfo<User> pageInfo = new PageInfo<>(list);
		pageBean.setCrurentNum(Integer.parseInt(pageNo));
		pageBean.setPageSize(Integer.parseInt(pageSize));
		pageBean.setTotalNum((int) pageInfo.getTotal());
		pageBean.setTotalPageSize(pageInfo.getPages());
		pageBean.setDatas(pageInfo.getList());
		return pageBean;
	}
	public Map<String,Object> getUserValue(String loginName){
		return userMapper.getUserValue(loginName);
	}

	public String findKey(String uuid,int loseTime){
		return userMapper.findKey(uuid,loseTime);
	}
	public MobileGxUser getGxUserCode(String uuid){
		return userMapper.getGxUserCode(uuid);
	}
	public List<UserMaterial> findUserMaterial(String idcard){
		return userMapper.findUserMaterial(idcard);
	}

	public int checkUserIp(String publicIp){
		return userMapper.checkUserIp(publicIp);
	}
	public int checkUserIpZF(String publicIp){
		return userMapper.checkUserIpZF(publicIp);
	}
	@Transactional(readOnly = false)
	public int  delUserValue(String loginName,String id){
		if(userMapper.delUserById(id) >= 1){
			if(userMapper.delUserRoleById(id) >= 1){
				if(userMapper.delUserByName(loginName) >= 1){
					userMapper.delUserMaterials(loginName);
					userMapper.delLegal(loginName);
					return 1;
				}
			}
		}
		return 0;
	}

	@Transactional(readOnly = false)
	public int  delLegal(String loginName){
		return userMapper.delLegal(loginName);
	}

	@Transactional(readOnly = false)
	public int  updateUserValue(String newtell,String loginName,String oldtell){
		if(userMapper.updateUserPhone(newtell,loginName,oldtell) >= 1){
			return userMapper.updateUserOpenid(newtell,loginName);
		}
		return 0;
	}

	@Transactional(readOnly = false)
	public void intoUserQR(String name,String idcard,String tell){
		userMapper.intoUserQR(name,idcard,tell, DateUtils.getDateTime());
	}

	/**
	 * 是否企业认证通过社会组织代码查询
	 * findlegalUser
	 * @return 受影响的行数
	 */
	public Integer findlegalUser(String socialCode,String loginName){
		return userMapper.findlegalUser(socialCode,loginName);
	}
	/**
	 * 是否企业认证通过关联微信id
	 * checklegalUser
	 * @return 受影响的行数
	 */
	public HashMap<String,Object> checklegalUser(String loginName){
		HashMap<String, Object> maps = userMapper.checklegalUser(loginName);
		String userValues;
		if(null != maps && null != maps.get("idcard")){
			userValues = maps.get("idcard").toString();
			maps.put("idcard",userValues.substring(0,6)+"********"+userValues.substring(15,userValues.length()));
			userValues = maps.get("tell").toString();
			maps.put("tell",userValues.substring(0,3)+"*****"+userValues.substring(8,userValues.length()));
			userValues = maps.get("socialCode").toString();
			maps.put("socialCode",userValues.substring(0,6)+"*****"+userValues.substring(15,userValues.length()));
		}
		return maps;
	}
	/**
	 * 添加企业信息
	 * intolegalUser
	 * @return 受影响的行数
	 */
	@Transactional(readOnly = false)
	public Integer intolegalUser(String legalName,String companyName,String socialCode,String idcard,String tell,String loginName,String pageUrl){

		Integer result = userMapper.updatelegalUser(legalName, companyName, socialCode, idcard, tell, DateUtils.getDateTime(), loginName,pageUrl);
		if(result <= 0){
			return userMapper.intolegalUser(legalName,companyName,socialCode,idcard,tell,DateUtils.getDateTime(),loginName,pageUrl);
		}else{
			return result;
		}
	}

	public String findPageUrl(String loginName){
		return userMapper.findPageUrl(loginName);
	}

	@Transactional(readOnly = false)
	public Integer updatelegalUserImg(String companyName,String ocrBack,String ocrFront,String idcard,String bizToken,String loginName){
		return userMapper.updatelegalUserImg(companyName,ocrBack,ocrFront,idcard,bizToken,loginName);
	}

	@Transactional(readOnly = false)
	public Integer intoUserCheck(String loginName,String BizToken){
		return userMapper.intoUserCheck(loginName,DateUtils.getDateTime(),BizToken);
	}



	public Boolean findUserCheck(String loginName){
		if(userMapper.findUserCheck(loginName) >= 1)return true;
		else return false;
	}

	public HashMap<String,String> getUserValueById(String id){
		return userMapper.getUserValueById(id);
	}

	public Boolean checklegalUserCount(String loginName){
		if(userMapper.checklegalUserCount(loginName) >= 1){
			return true;
		}else{
			return false;
		}
	}

	public List<HashMap<String,String>> legalList(String loginName){
		List<HashMap<String, String>> maps = userMapper.legalList(loginName);
		String values;
		for(HashMap<String, String> m : maps){
			values = m.get("tell");
			m.put("tell",values.substring(0,3)+"*****"+values.substring(values.length()-3,values.length()));
			values = m.get("idcard");
			m.put("idcard",values.substring(0,6)+"********"+values.substring(values.length()-4,values.length()));

		}
		return maps;
	}

	public HashMap<String,String> legalByIdcard(String idcard){
		HashMap<String, String> maps = userMapper.legalByIdcard(idcard);
		if(null != maps){
			String values = maps.get("tell");
			maps.put("tell",values.substring(0,3)+"*****"+values.substring(values.length()-3,values.length()));
			values = maps.get("name");
			maps.put("name",values.substring(0,1)+"**");
			values = maps.get("idcard");
			maps.put("idcard",values.substring(0,6)+"********"+values.substring(values.length()-4,values.length()));
			if(maps.containsKey("isCheck")){
				maps.put("isCheck","已授权");
			}else{
				maps.put("isCheck","未授权");
				maps.put("createTime","暂无");
			}
		}
		return maps;
	}

	@Transactional(readOnly = false)
	public Integer intolegalUserAll(String id){
		HashMap<String, String> maps = userMapper.findLegalValue(UserUtils.getUser().getLoginName());
		maps.put("loginName",id);
		maps.put("createTime",DateUtils.getDateTime());
		return userMapper.intolegalUserAll(maps);

	}

	public HashMap<String,String> getUserByToken(String loginName){
		return userMapper.getUserByToken(loginName);
	}


	/**
	 * 获取人才用户数据
	 * getUserByToken
	 * @return 受影响的行数
	 */
	public MobileRC getUserRC(String loginName){
		return userMapper.getUserRC(loginName);
	}

	/**
	 * 获取一码办成事用户数据
	 * ymbcsUserByTell
	 * @return 受影响的行数
	 */
	public YmbcsUserZF ymbcsUserByTell(String tell){
		return userMapper.ymbcsUserByTell(tell);
	}

	/**
	 * 获取用户名
	 * findLoginName
	 * @return 受影响的行数
	 */
	public String findLoginName(String tell){
			return userMapper.findLoginName(tell);
	}

	/**
	 * 获取用户名  第三方
	 * findLoginName
	 * @return 受影响的行数
	 */
	public String findLoginNameOther(String tell){
		return userMapper.findLoginNameOther(tell);
	}

	/**
	 * 获取用户名id
	 * findIdByLoginName
	 * @return 受影响的行数
	 */
	public String findIdByLoginName(String loginName){
		return userMapper.findIdByLoginName(loginName);
	}
	/**
	 * intoUserLog
	 * @return
	 */
	@Transactional(readOnly = false)
	public void intoUserLog(String userName,String doTime,String publicIp){
		mapper.intoUserLog(userName,doTime,publicIp);
	}

	/**
	 * 登录ip次数判断
	 * @intoUserLog
	 * @see [类、类#方法、类#成员]
	 */
	public int checkLoginIp(String publicIp){
		return mapper.checkLoginIp(publicIp);
	}

	public Integer findUserLog(String userName){
		return mapper.findUserLog(userName);
	}

	/**
	 * 查询企业信息
	 * @findUserLog
	 * @see [类、类#方法、类#成员]
	 */
	public YmbcsCompany findCompany(String loginName){
		return mapper.findCompany(loginName);
	}

	/**
	 * 获取法人基础信息
	 * getLegalValue
	 * @return 受影响的行数
	 */
	public MobileLegal getLegalValue(String loginName){
		return mapper.getLegalValue(loginName);
	}

	/**
	 * 获取扫码用户数据
	 * ymbcsUserValueQR
	 * @return 受影响的行数
	 */
	public HashMap<String,String> ymbcsUserValueQR(String uuid){
		return mapper.ymbcsUserValueQR(uuid);
	}

	/**
	 * 判断该二维码是否已扫码使用 禁止重复扫码
	 * @checkUUID
	 * @see [类、类#方法、类#成员]
	 */
	public Integer checkUUID(String uuid){
		return mapper.checkUUID(uuid);
	}

	/**
	 * 添加扫码记录
	 * @checkUUID
	 * @see [类、类#方法、类#成员]
	 */
	@Transactional(readOnly = false)
	public void intoQJQR(String qjQR,String loginName){
		mapper.intoQJQR(qjQR,loginName);
	}

	/**
	 * 更新扫码记录
	 * @checkUUID
	 * @see [类、类#方法、类#成员]
	 */
	@Transactional(readOnly = false)
	public void updateQJQRStatus(String loginName){
		mapper.updateQJQRStatus(loginName);
	}

	/**
	 * 统计扫码记录
	 * @findCountQR
	 * @see [类、类#方法、类#成员]
	 */
	public Integer findCountQR(String qjQR){
		return mapper.findCountQR(qjQR);
	}

	/**
	 * 群众操作记录
	 * @intoUserHistory
	 * @see [类、类#方法、类#成员]
	 */
	@Transactional(readOnly = false)
	public void intoUserHistory(String openid,String doMthod,String doResult,String number,String areaId,String tell){
		try {
			mapper.intoUserHistory(openid,doMthod,doResult,number,areaId,tell);
		}catch (Exception e){
			e.printStackTrace();
		}

	}

	/**
	 * 获取用户信息
	 * @getUserCompany
	 * @see [类、类#方法、类#成员]
	 */
	public HashMap<String,String> getUserCompany(String loginName){
		return mapper.getUserCompany(loginName);
	}
}
